package com.bix.util.blizfiles.m2;

import java.nio.ByteBuffer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.bix.util.blizfiles.BufferUtils;
import com.jme.math.Vector3f;

/**
 * This class encapsulates an animation sequence read from the M2 file.
 * 
 * @author squid
 * 
 */
public class M2AnimationSequence {
	private Log log = LogFactory.getLog (M2AnimationSequence.class);

	//
	// Animation ID in AnimationData.dbc.
	//
	private short animationId;

	//
	// Sub-animation id: Which number in a row of animations is this one.
	//
	private short subAnimationId;

	//
	// The length of the animation. This is not the number of timestamps in the
	// animation, but the number of "frames" or "steps" in the animation.
	//
	private int length;

	//
	// As 2.x says: moving speed for walk/run animations.
	//
	private float movingSpeed;

	//
	// Most likely...
	//
	// Squid: I believe that bit 5 implies that the animation is in the M2 file
	// whereas the absence of this bit means that the animation is in a
	// .anim file. Example: 0x20 means the animation sequence is in the
	// M2 file and 0x00 means it's in a .anim file. The name of the .anim
	// file is the name of the .M2 file followed by a four digit number
	// that includes the animationId, followed by -00.anim. I'm not
	// exactly sure what the -00 is for... maybe for subanimations? So
	// for the Hyena.M2 file, and animationId 69, the name of the file
	// would be: Hyena0069-00.anim.
	//
	private int flags;

	//
	// Only the first four bits are the actual flags. The rest is 1.
	//
	private int flags2;

	//
	// These next two are connected. Most of the time, they are 0.
	//
	private int unknown1;
	private int unknown2;

	//
	// Values: 0, 50, 100, 150, 200, 250, 300, 350, 500.
	//
	private int playbackSpeed;

	//
	// A bounding box made out of 2 vectors.
	//
	private Vector3f boundingBoxVector1;
	private Vector3f boundingBoxVector2;

	//
	// The radius.
	//
	private float radius;

	//
	// Id of the following animation of this AnimationID, points to an index or
	// is -1 if none.
	//
	private short nextAnimation;

	//
	// Id in the list of animations.
	//
	private short index;

	public M2AnimationSequence() {
	}

	public M2AnimationSequence(ByteBuffer bb) {
		read (bb);
	}

	public void read (ByteBuffer bb) {
		this.animationId = bb.getShort ();
		this.subAnimationId = bb.getShort ();
		this.length = bb.getInt ();
		this.movingSpeed = bb.getFloat ();
		this.flags = bb.getInt ();
		this.flags2 = bb.getInt ();
		this.unknown1 = bb.getInt ();
		this.unknown2 = bb.getInt ();
		this.playbackSpeed = bb.getInt ();
		this.boundingBoxVector1 = BufferUtils.getVector3f (bb);
		this.boundingBoxVector2 = BufferUtils.getVector3f (bb);
		this.radius = bb.getFloat ();
		this.nextAnimation = bb.getShort ();
		this.index = bb.getShort ();

		log.debug ("  animationId[" + this.getAnimationId () + "]");
		log.debug ("  subAnimationId[" + this.getSubAnimationId () + "]");
		log.debug ("  length[" + this.getLength () + "]");
		log.debug ("  movingSpeed[" + this.getMovingSpeed () + "]");
		log.debug ("  flags[0x" + Integer.toHexString (this.getFlags ()) + "]");
		log.debug ("  flags2[0x" + Integer.toHexString (this.getFlags2 ()) + "]");
		log.debug ("  unknown1[" + this.getUnknown1 () + "]");
		log.debug ("  unknown2[" + this.getUnknown2 () + "]");
		log.debug ("  playbackSpeed[" + this.getPlaybackSpeed () + "]");
		log.debug ("  boundingBoxVector1[" + this.getBoundingBoxVector1 ().getX () + ","
				+ this.getBoundingBoxVector1 ().getY () + "," + this.getBoundingBoxVector1 ().getZ () + "]");
		log.debug ("  boundingBoxVector2[" + this.getBoundingBoxVector2 ().getX () + ","
				+ this.getBoundingBoxVector2 ().getY () + "," + this.getBoundingBoxVector2 ().getZ () + "]");
		log.debug ("  radius[" + this.getRadius () + "]");
		log.debug ("  nextAnimation[" + this.getNextAnimation () + "]");
		log.debug ("  index[" + this.getIndex () + "]");
	}

	/**
	 * @return the animationId
	 */
	public short getAnimationId () {
		return animationId;
	}

	/**
	 * @return the subAnimationId
	 */
	public short getSubAnimationId () {
		return subAnimationId;
	}

	/**
	 * @return the length
	 */
	public int getLength () {
		return length;
	}

	/**
	 * @return the movingSpeed
	 */
	public float getMovingSpeed () {
		return movingSpeed;
	}

	/**
	 * @return the flags
	 */
	public int getFlags () {
		return flags;
	}

	/**
	 * @return the flags2
	 */
	public int getFlags2 () {
		return flags2;
	}

	/**
	 * @return the unknown1
	 */
	public int getUnknown1 () {
		return unknown1;
	}

	/**
	 * @return the unknown2
	 */
	public int getUnknown2 () {
		return unknown2;
	}

	/**
	 * @return the playbackSpeed
	 */
	public int getPlaybackSpeed () {
		return playbackSpeed;
	}

	/**
	 * @return the radius
	 */
	public float getRadius () {
		return radius;
	}

	/**
	 * @return the nextAnimation
	 */
	public short getNextAnimation () {
		return nextAnimation;
	}

	/**
	 * @return the index
	 */
	public short getIndex () {
		return index;
	}

	/**
	 * @return the boundingBoxVector1
	 */
	public Vector3f getBoundingBoxVector1 () {
		return boundingBoxVector1;
	}

	/**
	 * @return the boundingBoxVector2
	 */
	public Vector3f getBoundingBoxVector2 () {
		return boundingBoxVector2;
	}
}
